package me.sealer.ssm.controller;

import lombok.extern.slf4j.Slf4j;
import me.sealer.ssm.constant.Dict;
import me.sealer.ssm.constant.ErrorCodeConstant;
import me.sealer.ssm.constant.PermissionConstant;
import me.sealer.ssm.constant.RoleConstant;
import me.sealer.ssm.constant.SsmConstant;
import me.sealer.ssm.model.User;
import me.sealer.ssm.service.UserService;
import me.sealer.ssm.utils.MessageConverterUtil;
import me.sealer.ssm.utils.StringUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * @author sealer
 * @date 2016/09/27
 */
@Slf4j
@Controller
@RequestMapping("/userOperations")
@RequiresPermissions(value = {PermissionConstant.USER_MGMT})
public class UserController {
    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    /**
     * 查询所用用户方法
     *
     * @return
     * @throws Exception
     */
    @RequestMapping("/queryAllUsers")
    @RequiresRoles(value = {RoleConstant.ROLE_ADMIN})
    public ModelAndView queryAllUsers() throws Exception {
        ModelAndView modelAndView = new ModelAndView();

        //调用service方法得到用户列表
        List<User> users = userService.queryUserList();
        //将得到的用户列表内容添加到ModelAndView中
        modelAndView.addObject(Dict.USERS, users);
        //设置响应的jsp视图
        modelAndView.setViewName("userRoleMgmt");

        return modelAndView;
    }

    @RequestMapping(value = "/passwordModifyPre")
    public ModelAndView modifyPasswordPre() throws Exception {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("passwordModify");
        return modelAndView;
    }

    @RequestMapping(value = "/passwordModify", method = RequestMethod.POST)
    public ModelAndView modifyPassword(HttpServletRequest request) throws Exception {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("redirect:/preLogin");

        String oldPassword = request.getParameter(Dict.OLD_PASSWORD);
        String password = request.getParameter(Dict.PASSWORD);
        String confirmPassword = request.getParameter(Dict.CONFIRM_PASSWORD);

        String username = SecurityUtils.getSubject().getPrincipal().toString();
        User user = userService.findUserByUsername(username);

        String oldRealPasswordHex = user.getPassword();
        int saltId = user.getId();

        // 判断二次输入的新确认密码是否与新设置的密码相同
        boolean passNewConfirmEquals = StringUtil.equals(password, confirmPassword);
        if (!passNewConfirmEquals) {
            String message = MessageConverterUtil.getMessage(request, ErrorCodeConstant.USER_PASSWORD_CONFIRM_WRONG);
            modelAndView.addObject(SsmConstant.RESULT_MESSAGE, message);
            modelAndView.setViewName("passwordModify");
            return modelAndView;
        }

        // 判断输入的旧密码是否一致
        String oldPasswordHex = DigestUtils.md5DigestAsHex((saltId + oldPassword).getBytes((StandardCharsets.UTF_8)));
        boolean isPermitted = StringUtil.equals(oldRealPasswordHex, oldPasswordHex);
        if (!isPermitted) {
            String message = MessageConverterUtil.getMessage(request, ErrorCodeConstant.USER_LOGIN_PASSWORD_WRONG);
            modelAndView.addObject(SsmConstant.RESULT_MESSAGE, message);
            modelAndView.setViewName("passwordModify");
            return modelAndView;
        }

        // 判断新老密码是否相同
        boolean passNewOldEquals = StringUtil.equals(oldPassword, password);
        if (passNewOldEquals) {
            String message = MessageConverterUtil.getMessage(request, ErrorCodeConstant.USER_PASSWORD_NEW_OLD_SAME);
            modelAndView.addObject(SsmConstant.RESULT_MESSAGE, message);
            modelAndView.setViewName("passwordModify");
            return modelAndView;
        }

        // 检验通过， 修改密码， 更新数据库， 登出弹窗， 重新登录。
        String newPasswordHex = DigestUtils.md5DigestAsHex((saltId + password).getBytes(StandardCharsets.UTF_8));
        User newUser = User.builder()
                .password(newPasswordHex)
                .id(saltId)
                .build();

        userService.updateUser(newUser);

        Subject subject = SecurityUtils.getSubject();
        SecurityUtils.getSecurityManager().logout(subject);
        return modelAndView;
    }
}
